#include "ringbuffer.h"
#include <cstring>
#include <algorithm>

RingbufferNormal::RingbufferNormal(unsigned int ringlen) : read(0), write(0), len(ringlen)
{
	dataarea = new unsigned char[len];
}

RingbufferNormal::~RingbufferNormal()
{
	delete[] dataarea;
}

unsigned long long RingbufferNormal::length()
{
	return write - read;
}

unsigned long long RingbufferNormal::unuselen()
{
	return len - length();
}

bool RingbufferNormal::PushData(unsigned char *data, unsigned long long datalen)
{
	if (datalen > unuselen())
	{
		return false;
	}
	unsigned long long l = std::min(datalen, len - (write % len));
	memcpy(dataarea + (write % len), data, l);
	memcpy(dataarea, data + l, datalen - l);
	write += datalen;
	return true;
}

unsigned long long RingbufferNormal::PeekData(unsigned char *data, unsigned long long datalen)
{
	unsigned long long cplen = std::min(datalen, length());
	unsigned long long l = std::min(datalen, len - (read % len));
	memcpy(data, dataarea + (read % len), l);
	memcpy(data + l, dataarea, cplen - l);
	return cplen;
}

unsigned int RingbufferNormal::PopData(unsigned char *data, unsigned long long datalen)
{
	unsigned long long cplen = PeekData(data, datalen);
	read += cplen;
	return cplen;
}
